package com.weixin.message.common;

import java.awt.Color;
import java.awt.Font;
import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import com.foxinmy.weixin4j.exception.WeixinException;
import com.foxinmy.weixin4j.model.media.MediaUploadResult;
import com.foxinmy.weixin4j.model.qr.QRParameter;
import com.foxinmy.weixin4j.model.qr.QRResult;
import com.foxinmy.weixin4j.mp.WeixinProxy;
import com.foxinmy.weixin4j.mp.api.MediaApi;
import com.foxinmy.weixin4j.mp.api.NotifyApi;
import com.foxinmy.weixin4j.mp.api.QrApi;
import com.foxinmy.weixin4j.mp.message.NotifyMessage;
import com.foxinmy.weixin4j.tuple.Text;
import com.weixin.message.common.message.Image;
import com.weixin.message.common.message.WeixinResponse;
import com.weixin.message.common.message.req.ImageMessage;
import com.weixin.message.common.message.req.LinkMessage;
import com.weixin.message.common.message.req.LocationMessage;
import com.weixin.message.common.message.req.TextMessage;
import com.weixin.message.common.message.req.VoiceMessage;
import com.weixin.message.common.message.req.event.EventMessage;
import com.weixin.message.common.message.resp.ImageResponse;
import com.weixin.message.common.message.resp.NoReplyResponse;
import com.weixin.message.common.message.resp.TextResponse;
import com.weixin.message.common.util.ImageHandleHelper;

import me.firstapp.module.weixin.member.Member;
import me.firstapp.service.weixin.member.MemberService;
import me.firstapp.service.weixin.member.SpreadOrderService;

/**
 * 消息处理
 *
 */
public class MessageProcessor extends WeixinMessageProcessor {

	private static Logger logger = LoggerFactory.getLogger(MessageProcessor.class);

	@Autowired
	private MemberService memberService;

	@Autowired
	private SpreadOrderService spreadOrderService;

	@Autowired
	private WeixinProxy weixinProxy;

	@Override
	protected WeixinResponse onText(TextMessage message) {
		// TextResponse resp = RespMessageFactory.buildTextResponse("您发的消息为:" +
		// message.getContent(), message);
		return NoReplyResponse.get();
	}

	@Override
	protected WeixinResponse onImage(ImageMessage message) {
		// TextResponse resp = RespMessageFactory.buildTextResponse("您发的图片为:" +
		// message.getPicUrl(), message);
		return NoReplyResponse.get();
	}

	@Override
	protected WeixinResponse onLink(LinkMessage message) {
		// TextResponse resp = RespMessageFactory.buildTextResponse("您发的链接为:" +
		// message.getUrl(), message);
		return NoReplyResponse.get();
	}

	@Override
	protected WeixinResponse onLocation(LocationMessage message) {
		// TextResponse resp = RespMessageFactory.buildTextResponse(
		// "您发的地址为: {x=" + message.getLocation_X() + ",y=" +
		// message.getLocation_Y() + "}", message);
		return NoReplyResponse.get();
	}

	@Override
	protected WeixinResponse onVoice(VoiceMessage message) {
		// TextResponse resp =
		// RespMessageFactory.buildTextResponse("您发的语音为:mediaId=" +
		// message.getMediaId(), message);
		return NoReplyResponse.get();
	}

	@Override
	protected WeixinResponse onEvent(EventMessage message) {
		try {
			if ("subscribe".equals(message.getEvent())) {// 用户未关注时，进行关注后的事件推送
				String openId = message.getFromUserName();
				String chiefOpenId = "";
				String eventKey = message.getEventKey();
				if ("".equals(eventKey) || null == eventKey) {
					chiefOpenId = "otFms0ib9eecFHRe2pa98b-Bfjh0";
				} else {
					String[] params = eventKey.split("_");
					chiefOpenId = params[1];
				}
				Member member = memberService.findMemberByOpenId(openId);
				if (null != member) {
					member.setFollowStatus(Member.FOLLOW_STATUS_YES);
					member = memberService.executeUpdateMember(member);
					logger.info("用户openId=" + openId + "已存在");
					return NoReplyResponse.get();
				} else {
					member = memberService.executeAddMember(openId, chiefOpenId, null, null, null, null);
					try {
						if (!openId.equals(chiefOpenId)) {
							spreadOrderService.executeAdd(chiefOpenId, openId);
						}
					} catch (Exception e) {
						logger.error("addMemberFromMessage.do添加推广单失败", e);
						e.printStackTrace();
					}
					TextResponse textResponse = new TextResponse();
					textResponse.setToUserName(openId);
					textResponse.setFromUserName(message.getToUserName());
					textResponse.setContent("欢迎来到贝通商城，您的ID为：" + member.getCardNo() + "，已赠送您100积分，请在底部的【个人中心-->我的账户】查看");
					textResponse.setFuncFlag(0x0001);
					return textResponse;
				}

			} else if ("SCAN".equals(message.getEvent())) {// 用户已关注时的事件

			} else if ("CLICK".equals(message.getEvent())) {// 点击菜单事件
				String openId = message.getFromUserName();
				if ("123321".equals(message.getEventKey())) {// 点击领二维码菜单
					try {
						NotifyApi notifyApi = new NotifyApi(weixinProxy.getTokenManager());
						notifyApi.sendNotify(new NotifyMessage(openId, new Text("正在为您生成二维码，请稍等...")));
					} catch (WeixinException e) {
						e.printStackTrace();
					}
					Member member = memberService.findMemberByOpenId(openId);
					String avatar = member.getAvatar();
					String name = member.getName();
					try {
						// 生成带参数的二维码
						QrApi qrApi = new QrApi(weixinProxy.getTokenManager());
						// 创建临时二维码(场景值为string),二维码有效时间，以秒为单位。
						// 最大不超过2592000（即30天）
						QRParameter qRParameter = QRParameter.createTemporaryQR(2592000, openId);
						QRResult qRResult = qrApi.createQR(qRParameter);
						byte[] qr = qRResult.getContent();

						// 合并二维码图片
						File smallImage = new File("/mnt/images/" + openId + ".jpg");
						OutputStream output = new FileOutputStream(smallImage);
						@SuppressWarnings("resource")
						BufferedOutputStream bufferedOutput = new BufferedOutputStream(output);
						bufferedOutput.write(qr);
						File bigImage = new File("/mnt/images/tuiguang.jpg");
						File resultFile0 = ImageHandleHelper.overlapImage(bigImage, smallImage,
								"/mnt/images/" + openId + ".jpg", 200, 120, 230, 230);

						// 合并头像
						// new一个URL对象
						URL avatarUrl = new URL(avatar);
						// 打开链接
						HttpURLConnection conn = (HttpURLConnection) avatarUrl.openConnection();
						// 设置请求方式为"GET"
						conn.setRequestMethod("GET");
						// 超时响应时间为5秒
						conn.setConnectTimeout(5 * 1000);
						// 通过输入流获取图片数据
						InputStream inStream = conn.getInputStream();
						// 得到图片的二进制数据，以二进制封装得到数据，具有通用性
						byte[] avatarData = readInputStream(inStream);
						// new一个文件对象用来保存图片，默认保存当前工程根目录
						File avatarFile = new File("/mnt/images/avatar_" + openId + ".jpg");
						// 创建输出流
						FileOutputStream outStream = new FileOutputStream(avatarFile);
						// 写入数据
						outStream.write(avatarData);
						// 关闭输出流
						outStream.close();

						File resultFile1 = ImageHandleHelper.overlapImage(resultFile0, avatarFile,
								"/mnt/images/" + openId + ".jpg", 210, 370, 60, 60);
						// // 写入昵称
						File resultFile2 = ImageHandleHelper.exportImg2(name, resultFile1.getPath(),
								"/mnt/images/nameresult_" + openId + ".jpg", 320, 400, 24, Font.PLAIN, Color.red);
						// 写入日期
						Date expireDate = getBeforeOrNextDay(new Date(), 30);
						File resultFile3 = ImageHandleHelper.exportImg2(getDateStr(expireDate, "yyyy年MM月dd日"),
								resultFile2.getPath(), "/mnt/images/dateresult_" + openId + ".jpg", 317, 872, 20,
								Font.PLAIN, Color.black);

						// 通过素材管理接口上传合并后的图片到微信服务器
						MediaApi mediaApi = new MediaApi(weixinProxy.getTokenManager());
						MediaUploadResult mediaUploadResult = mediaApi.uploadMedia(false,
								new FileInputStream(resultFile3), openId);
						String mediaId = mediaUploadResult.getMediaId();

						// 返回WeixinResponse
						ImageResponse imageResponse = new ImageResponse();
						imageResponse.setToUserName(openId);
						imageResponse.setFromUserName(message.getToUserName());
						Image image = new Image();
						image.setMediaId(mediaId);
						imageResponse.setImage(image);
						imageResponse.setFuncFlag(0x0001);
						return imageResponse;
					} catch (WeixinException e) {
						e.printStackTrace();
						logger.error("创建二维码图片出现异常", e);
					} catch (FileNotFoundException e) {
						e.printStackTrace();
						logger.error("创建二维码图片出现异常", e);
					} catch (IOException e) {
						e.printStackTrace();
						logger.error("创建二维码图片出现异常", e);
					} catch (Exception e) {
						e.printStackTrace();
						logger.error("创建二维码图片出现异常", e);
					}
				} else if ("888888".equals(message.getEventKey())) {
					TextResponse textResponse = new TextResponse();
					textResponse.setToUserName(openId);
					textResponse.setFromUserName(message.getToUserName());
					textResponse.setContent("用户通过你的二维码关注公众号后，你将获得10积分和1贝币（1贝币=1元），且该用户永久成为你的下级。积分可换购商品或转化为贝币，贝币可直接提现。");
					textResponse.setFuncFlag(0x0001);
					return textResponse;
				}

			} else if ("unsubscribe".equals(message.getEvent())) {
				String openId = message.getFromUserName();
				Member member = memberService.findMemberByOpenId(openId);
				member.setFollowStatus(Member.FOLLOW_STATUS_NO);
				memberService.executeUpdateMember(member);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return NoReplyResponse.get();// ruturn后可以回复用户消息
	}

	private byte[] readInputStream(InputStream inStream) throws Exception {
		ByteArrayOutputStream outStream = new ByteArrayOutputStream();
		// 创建一个Buffer字符串
		byte[] buffer = new byte[1024];
		// 每次读取的字符串长度，如果为-1，代表全部读取完毕
		int len = 0;
		// 使用一个输入流从buffer里把数据读取出来
		while ((len = inStream.read(buffer)) != -1) {
			// 用输出流往buffer里写入数据，中间参数代表从哪个位置开始读，len代表读取的长度
			outStream.write(buffer, 0, len);
		}
		// 关闭输入流
		inStream.close();
		// 把outStream里的数据写入内存
		return outStream.toByteArray();
	}

	private Date getBeforeOrNextDay(Date date, int n) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.add(Calendar.DAY_OF_MONTH, n);
		date = calendar.getTime();
		return date;
	}

	private String getDateStr(Date date, String pattern) {
		if (date == null) {
			return null;
		}
		SimpleDateFormat format = new SimpleDateFormat(pattern);
		return format.format(date);
	}
}
